
#ifndef __CSYMBOLFINDER_h__
#define __CSYMBOLFINDER_h__

#include <comip.h>	// _com_ptr_t

#include <vector>

#include "dia2.h"


#include "miscutil.h"

using namespace std;

typedef _com_ptr_t<_com_IIID<IDiaSymbol, &__uuidof(IDiaSymbol)> > IDiaSymbolPtr;
typedef _com_ptr_t<_com_IIID<IDiaDataSource, &__uuidof(IDiaDataSource)> > IDiaDataSourcePtr;
typedef _com_ptr_t<_com_IIID<IDiaSession, &__uuidof(IDiaSession)> > IDiaSessionPtr;
typedef _com_ptr_t<_com_IIID<IDiaEnumSymbols, &__uuidof(IDiaEnumSymbols)> > IDiaEnumSymbolsPtr;


class CSymbolFinder
{
public:
	CSymbolFinder()
		:m_dwCompareFlags(0)
	{};

public:
	BOOL Init(const TCHAR* pszPdbFile);

public:
	// symtag: SymTagNull to find all types
	template<class T>	// T IDiaSymbol* or IDiaSymbolPtr
	BOOL FindSymbolS(const TCHAR* pszName, vector<T>* pv, enum SymTagEnum symtag=SymTagNull)
	{
		if(0==ForEachMatchSymblol(OnMatchSymbol<T, TRUE>, pszName, symtag))
		{
			return FALSE;
		}
		
		return TRUE;
	};

	template<class T>	// T IDiaSymbol* or IDiaSymbolPtr
	BOOL FindSymbol(const WCHAR* pwszName, T* psymb, enum SymTagEnum symtag=SymTagNull)
	{
		if(0==ForEachMatchSymblol(OnMatchSymbol<T, FALSE>, pszName, symtag))
		{
			return FALSE;
		}
		
		return TRUE;
	};

	BOOL FindBasicSymbol(BasicType btBaseType, DWORD dwLen, IDiaSymbol** psymb);

public:
	void SetCompareFlags(DWORD dwCompareFlags){m_dwCompareFlags=dwCompareFlags;};
	DWORD GetCompareFlags(){return m_dwCompareFlags;};


private:
typedef BOOL (CSymbolFinder::*pfnOnMatchSymbol)(VOID* pv, IDiaSymbol** psymb, enum SymTagEnum symtag);
	DWORD ForEachMatchSymblol(pfnOnMatchSymbol pfn, VOID* pv, const TCHAR* pszName, enum SymTagEnum symtag);

private:
	template<class T, BOOL ret>	// T IDiaSymbol* or IDiaSymbolPtr
	BOOL OnMatchSymbol(VOID* pv, IDiaSymbol** psymb, enum SymTagEnum symtag);

private:
	wstring m_wstrPdbFile;
	IDiaDataSourcePtr m_pDiaSrc;
	IDiaSessionPtr m_pSession;
	IDiaSymbolPtr m_pGlobal;
	
	DWORD m_dwCompareFlags;
	
};



#endif	//#ifndef __CSYMBOLFINDER_h__
